package com.bj.dz.controller;

import com.bj.dz.ResultModel.R;
import com.bj.dz.ResultModel.RHelper;
import com.bj.dz.ResultModel.ResponseCode;
import com.bj.dz.constant.Constant;
import com.bj.dz.entity.ReleaseSubtask;
import com.bj.dz.entity.ReleaseTask;
import com.bj.dz.entity.Users;
import com.bj.dz.service.ReleaseSubtaskService;
import com.bj.dz.service.ReleaseTaskService;
import com.bj.dz.service.UsersService;
import com.bj.dz.util.DateUtil;
import com.bj.dz.util.ExcelUtil;
import com.bj.dz.util.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 *   任务发布控制器
 */
@Slf4j
@Api(tags = "【任务发布】提供服务接口")
@RestController
@RequestMapping("/releaseTask")
public class ReleaseTaskController {

    @Resource
    private ReleaseTaskService releaseTaskService;
    @Resource
    private ReleaseSubtaskService releaseSubtaskService;
    @Resource
    private UsersService usersService;


    /**
     * 查询所有发布任务【根据模块(1建筑物2水3汽4交通5电力6通讯)以及状态为1(发布的)】及其对应的子任务
     *
     * @param
     * @return
     */
    @ApiOperation(value = "查询发布任务及其对应的子任务,根据不同模块【使用】")
    @RequestMapping(value = "/findAllTasks", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public R findAllTasks(@ApiParam(name = "type", value = "模块类型【1建筑物2水3汽4交通5电力6通讯】", required = true) @RequestParam(value = "type", required = true) Integer type) {
        R r = RHelper.ok();
        log.info("模块类型type为:" + type);
        //查询所有发布任务根据模块类型
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("type", type);//模块类型
        param.put("State", Constant.RELEASE_TASK_STATE_1);//状态为1

        List<ReleaseTask> releaseTaskList = releaseTaskService.getReleaseTaskListByMap(param);
        if (releaseTaskList != null) {
            for (int i = 0; i < releaseTaskList.size(); i++) {
                //获取发布任务的id
                ReleaseTask releaseTask = releaseTaskList.get(i);
                Integer id = releaseTask.getId();
                //通过id查询对应的子任务集合
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("type", id);
                List<ReleaseSubtask> releaseSubtaskList = releaseSubtaskService.getReleaseSubtaskListByMap(params);
                //0.设置发布任务对应的子任务集合
                releaseTask.setReleaseSubtaskList(releaseSubtaskList);
                //1.移除原来元素
                releaseTaskList.remove(i);
                //2.将新元素重新放入指定位置
                releaseTaskList.add(i, releaseTask);
            }
            r.setDatas(releaseTaskList);
        }
        return r;
    }

    /**
     * 查询所有发布任务【根据模块(1建筑物2水3汽4交通5电力6通讯)以及状态为1(发布的)-----7(入库状态)】【使用2】
     * 通过模块type和状态state【使用2】
     * 没有传入状态查询所有
     *
     * @param
     * @return
     */
    @ApiOperation(value = "查询发布任务,根据不同模块和状态【使用2】")
    @RequestMapping(value = "/findAllByType", method = RequestMethod.GET, produces = "application/json;" + "charset=UTF-8")
    public Page findAllByType(@ApiParam(name = "type", value = "模块类型【1建筑物2水3汽4交通5电力6通讯】", required = true)
                              @RequestParam(value = "type", required = true) Integer type,
                              @ApiParam(name = "state", value = "任务状态【1发布2认领3数据上传4提交质检5质检不合格6质检合格7数据入库】", required = false) @RequestParam(value = "state", required = false) Integer state,
                              @ApiParam(name = "page", value = "当前页", required = true) @RequestParam(value = "page", required = true) Integer page,
                              @ApiParam(name = "rows", value = "每页显示行数", required = true) @RequestParam(value = "rows", required = true) Integer rows) {
        log.info("模块类型type为:" + type);
        //查询所有发布任务根据模块类型
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("type", type);//模块类型
        if (state != null && state != 0) {
            param.put("State", state);
        }//设置状态
        //param.put("State", Constant.RELEASE_TASK_STATE_1);//状态为1
        Page<ReleaseTask> pageData = releaseTaskService.queryReleaseTaskPageByMap(param, page, rows);//分页相关的一切数据
        return pageData;
    }

    /**
     * 领导发布任务，根据不同模块type【使用2】
     *
     * @param
     * @return
     */
    @Async
    @ApiOperation(value = "发布任务接口【使用2】")
    @RequestMapping(value = "/uploadTask", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public Map<String, Object> uploadTask(@ApiParam(name = "nodeFile", value = "上传的excel文件", required = true) @RequestParam(value = "nodeFile", required = false) MultipartFile nodeFile,
                                          @ApiParam(name = "uploadFile", value = "上传的文件", required = true) @RequestParam(value = "uploadFile", required = false) MultipartFile uploadFile,
                                          @ApiParam(name = "taskName", value = "任务名称", required = true) @RequestParam(value = "taskName", required = true) String taskName,
                                          @ApiParam(name = "remark", value = "备注信息", required = true) @RequestParam(value = "remark", required = true) String remark,
                                          @ApiParam(name = "type", value = "模块类型", required = true) @RequestParam(value = "type", required = true) Integer type,
                                          HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();//返回前台参数
        System.out.println("**************************" + remark + "*******" + type + "*******" + taskName);
        //构建上传文件
        String fileNames = uploadFile.getOriginalFilename();//获取文件名字
        log.info("上传的文件为:" + fileNames);
        String suffix = fileNames.substring(fileNames.lastIndexOf("."));//包含.  不包含可以lastIndexOf(".") + 1
        log.info("上传的文件的后缀为:" + suffix);
        String fileName = fileNames.substring(0, fileNames.lastIndexOf("."));
        log.info("上传的文件的名字为:" + fileName);
        //拼接成 名字+当前时间+后缀
        Date nowDate = new Date();
        String strDate = DateUtil.dateToStr2(nowDate);
        log.info("当前日期为:" + strDate);
        String finalFileName = fileName + strDate + suffix;
        log.info("包装后的文件全名为:" + finalFileName);
        //String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();//获取resources目录路径
        String path = System.getProperty("user.dir");//项目目录
        //String path=request.getRealPath("/") + "demo/";
        log.info("项目根路径:" + path);
        try {
            uploadFile.transferTo(new File(path + "/doc", finalFileName));
        } catch (IOException e) {
            log.info("文件上传失败...............");
            result.put("flag", false);
            result.put("msg", "文件上传失败");
            e.printStackTrace();
            return result;
        }
        //获取文件访问地址
        //String url="http://"+req.getServerName()+":8080/demo/"+fileName;
        String url = "http://" + request.getServerName() //服务器地址
                + ":"
                + request.getServerPort()           //端口号
                + request.getContextPath() + "/"
                + finalFileName;
        log.info("访问压缩包文件的路径为:" + url);
        ReleaseTask releaseTask = new ReleaseTask();
        releaseTask.setTaskName(taskName);
        releaseTask.setRemark(remark);
        releaseTask.setUrl(url);
        releaseTask.setTime(new Date());
        releaseTask.setState(Constant.RELEASE_TASK_STATE_1);//设置状态为1
        releaseTask.setType(type);//设置模块状态
        boolean flag = releaseTaskService.addReleaseTask(releaseTask);
        Integer id = releaseTask.getId();
        flag = addReleaseSubtast(nodeFile, id);
        if (flag) {
            result.put("flag", true);
            result.put("msg", "上传任务成功");
        } else {
            result.put("flag", false);
            result.put("msg", "上传任务失败");
        }
        return result;
    }


    /**
     * 通过传taskId和userId【用户申领任务】
     *
     * @param
     * @return
     */
    @ApiOperation(value = "申请/申领任务【使用】")
    @RequestMapping(value = "/userGetTask", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public R userGetTask(@ApiParam(name = "userId", value = "用户的id", required = true) @RequestParam(value = "userId", required = true) Integer userId,
                         @ApiParam(name = "taskId", value = "任务的id", required = true) @RequestParam(value = "taskId", required = true) Integer taskId) {
        R r = RHelper.ok();
        log.info("userId为:" + userId + ",taskId为:" + taskId);
        //通过taskId查询对应的任务
        ReleaseTask releaseTask = releaseTaskService.getReleaseTaskById(taskId);
        if (releaseTask != null) {
            //判断是否有该用户
            Users user = usersService.getUsersById(userId);
            if (user != null) {
                //更新userId【就是谁认领的】,更新状态【认领后状态改为2(认领)】
                releaseTask.setUserId(userId);
                releaseTask.setState(Constant.RELEASE_TASK_STATE_2);
                boolean flag = releaseTaskService.modifyReleaseTask(releaseTask);
                if (flag) {
                    r.setMsg("申领任务成功");
                } else {
                    r.setCode(ResponseCode.FAILED_CODE);
                    r.setMsg("申领任务失败");
                }
            } else {
                r.setCode(ResponseCode.FAILED_CODE);
                r.setMsg("申领用户不存在，请检查");
            }
        } else {
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("没有找到对应任务，无法认领！请检查任务id是否正确");
        }
        return r;
    }

    /**
     * 上传任务接口mytask（用户id，任务id，压缩包,保存自己的服务器时间,保存url【添加到task_record表】）
     * 更新release_task表中的updateUrl以及udateTime，还用状态State【3上传】
     *
     * @param
     * @return
     */
    @ApiOperation(value = "用户上传任务接口(用户id，任务id，压缩包)【使用】")
    @RequestMapping(value = "/uploadUserTask", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public R uploadUserTask(@ApiParam(name = "uploadFile", value = "上传的文件", required = true) @RequestParam(value = "uploadFile", required = true) MultipartFile uploadFile,
                            @ApiParam(name = "taskId", value = "任务id", required = true) @RequestParam(value = "taskId", required = true) Integer taskId,
                            @ApiParam(name = "userId", value = "用户id", required = true) @RequestParam(value = "userId", required = true) Integer userId,
                            HttpServletRequest request) {
        log.info("上传用户任务........用户id为:" + userId + ",任务id为:" + taskId);
        R r = RHelper.ok();
        //检查用户和任务id是否存在和匹配
        //通过taskId查询对应的任务
        ReleaseTask releaseTask = releaseTaskService.getReleaseTaskById(taskId);
        if (releaseTask == null) {
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("没有找到对应任务，请检查任务id");
            return r;
        }
        //判断是否有该用户
        Users user = usersService.getUsersById(userId);
        if (user == null) {
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("用户不存在，请检查用户id");
            return r;
        }
        //判断是否匹配
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", taskId);//设置taskId
        params.put("userId", userId);//设置userId
        List<ReleaseTask> releaseTaskList = releaseTaskService.getReleaseTaskListByMap(params);
        if (releaseTaskList.isEmpty()) {
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("用户和自己的任务不匹配，请检查");
            return r;
        }
        //构建上传文件
        String fileNames = uploadFile.getOriginalFilename();//获取文件名字
        log.info("上传的文件为:" + fileNames);
        String suffix = fileNames.substring(fileNames.lastIndexOf("."));//包含.  不包含可以lastIndexOf(".") + 1
        log.info("上传的文件的后缀为:" + suffix);
        String fileName = fileNames.substring(0, fileNames.lastIndexOf("."));
        log.info("上传的文件的名字为:" + fileName);
        //拼接成 名字+当前时间+后缀
        Date nowDate = new Date();
        String strDate = DateUtil.dateToStr2(nowDate);
        log.info("当前日期为:" + strDate);
        String finalFileName = fileName + strDate + suffix;
        log.info("包装后的文件全名为:" + finalFileName);
        //String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();//获取resources目录路径
        String path = System.getProperty("user.dir");//项目目录
        //String path=request.getRealPath("/") + "demo/";
        log.info("项目根路径:" + path);
        try {
            uploadFile.transferTo(new File(path + "/doc", finalFileName));
        } catch (IOException e) {
            log.info("文件上传失败...............");
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("文件上传失败");
            e.printStackTrace();
            return r;
        }
        //获取文件访问地址
        //String url="http://"+req.getServerName()+":8080/demo/"+fileName;
        String url = "http://" + request.getServerName() //服务器地址
                + ":"
                + request.getServerPort()           //端口号
                + request.getContextPath() + "/"
                + finalFileName;
        log.info("访问压缩包文件的路径为:" + url);
        boolean flag = releaseTaskService.uploadUserTask(taskId, userId, url, nowDate);
        if (flag) {
            r.setMsg("上传任务成功");
            r.setDatas(url);
        } else {
            r.setCode(ResponseCode.FAILED_CODE);
            r.setMsg("上传任务失败");
        }
        return r;
    }

    /**
     * 查找用户对应的已认领任务(包括子任务),根据不同模块
     *
     * @param
     * @return
     */
    @ApiOperation(value = "查找用户对应的任务(包括子任务),根据不同模块【使用】")
    @RequestMapping(value = "/findByUserIdTasks", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public R findByUserId(@ApiParam(name = "userId", value = "用户的id", required = true) @RequestParam(value = "userId", required = true) Integer userId,
                          @ApiParam(name = "type", value = "模块类型【1建筑物2水3汽4交通5电力6通讯】", required = true) @RequestParam(value = "type", required = true) Integer type) {
        R r = RHelper.ok();
        log.info("userId为:" + userId + ",模块类型type为:" + type);
        //通过userId查询对应的任务Id集合，查询所有发布任务根据模块类型
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type", type);//根据模块类型
        params.put("userId", userId);//根据用户
        List<ReleaseTask> mytaskList = releaseTaskService.getReleaseTaskListByMap(params);
        if (mytaskList != null) {
            log.info("用户对应的任务个数为:" + mytaskList.size());
            for (int i = 0; i < mytaskList.size(); i++) {
                ReleaseTask mytask = mytaskList.get(i);
                //获取taskId
                Integer taskId = mytask.getId();
                log.info("任务id为:" + taskId);
                //查询对应的子任务
                Map<String, Object> params2 = new HashMap<String, Object>();
                params2.put("type", taskId);
                List<ReleaseSubtask> releaseSubtaskList = releaseSubtaskService.getReleaseSubtaskListByMap(params2);
                if (releaseSubtaskList != null) {
                    log.info("任务对应id为" + taskId + ",子任务有:" + releaseSubtaskList.size() + "个");
                    mytask.setReleaseSubtaskList(releaseSubtaskList);
                    mytaskList.remove(i);
                    mytaskList.add(i, mytask);
                }
            }
            r.setDatas(mytaskList);
        }
        return r;
    }


    /**
     * 通过id查询
     *
     * @param
     * @return
     */
    @ApiOperation(value = "查找服务")
    @RequestMapping(value = "/findById", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public ReleaseTask findReleaseTaskById(@ApiParam(name = "id", value = "ReleaseTask的id", required = true) @RequestParam(value = "id", required = true) Integer id) {
        return releaseTaskService.getReleaseTaskById(id);
    }

    /**
     * 子任务exce解析
     *
     * @param file
     * @param type
     * @return
     */
    @ApiOperation(value = "子任务excel解析")
    @RequestMapping(value = "/upExcel", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public boolean addReleaseSubtast(@ApiParam(name = "file", value = "上传的Excel文件", required = true) @RequestParam(value = "file", required = true) MultipartFile file,
                                     @ApiParam(name = "type", value = "子任务对应的主任务id", required = true) @RequestParam(value = "type", required = true) Integer type) {
        List<ReleaseSubtask> releaseSubtasks = null;
        boolean flag = false;
        try {
            releaseSubtasks = ExcelUtil.importExcel(file.getInputStream(), "yyyy-MM-dd hh:mm:ss", 0, 1, 0, ReleaseSubtask.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
//        assert releaseSubtasks != null;
        for (ReleaseSubtask r : releaseSubtasks) {
            r.setType(type);
            flag = releaseSubtaskService.addReleaseSubtask(r);
            if (!flag) {
                return false;
            }
            System.out.println(r);
        }
        return flag;
    }


    /**
     * 通过多个查询
     *
     * @param
     * @return
     */
    @ApiOperation(value = "查找多个服务")
    @RequestMapping(value = "/findReleaseTasks", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public List<ReleaseTask> findReleaseTaskListByMap(@ApiParam(name = "ReleaseTask", value = "releaseTask", required = true) @RequestBody ReleaseTask releaseTask) {

        return releaseTaskService.getReleaseTaskListByMap(null);
    }

    /**
     * 查询总数【根据模块(1建筑物2水3汽4交通5电力6通讯)】
     *
     * @param
     * @return
     */
    @ApiOperation(value = "获取总数服务")
    @RequestMapping(value = "/count", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public Integer ReleaseTaskCount(@ApiParam(name = "type", value = "模块类型【1建筑物2水3汽4交通5电力6通讯】", required = true) @RequestParam(value = "type", required = true) Integer type) {
        log.info("模块类型type为:" + type);
        //查询所有发布任务根据模块类型
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("type", type);//模块类型
        return releaseTaskService.getReleaseTaskCountByMap(param);
    }

    /**
     * 添加保存
     *
     * @param
     * @return
     */
    @ApiOperation(value = "添加服务")
    @RequestMapping(value = "/add", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public boolean addReleaseTask(@ApiParam(name = "ReleaseTask", value = "releaseTask对象", required = true) @RequestBody ReleaseTask releaseTask) {
        return releaseTaskService.addReleaseTask(releaseTask);
    }

    /**
     * 更新修改
     *
     * @param
     * @return
     */
    @ApiOperation(value = "更新修改服务")
    @RequestMapping(value = "/upd", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public boolean modifyReleaseTask(@ApiParam(name = "ReleaseTask", value = "releaseTask对象", required = true) @RequestBody ReleaseTask releaseTask) {
        return releaseTaskService.modifyReleaseTask(releaseTask);
    }

    /**
     * 删除【使用2】
     *
     * @param
     * @return
     */
    @ApiOperation(value = "删除服务【使用2】")
    @RequestMapping(value = "/del", method = RequestMethod.POST, produces = "application/json;" + "charset=UTF-8")
    public boolean deleteReleaseTaskById(@ApiParam(name = "删除服务", value = "任务id", required = true) @RequestParam(value = "id", required = true) Integer id) {
        boolean flag = releaseSubtaskService.deleteReleaseSubtaskById(id);
        flag = releaseTaskService.deleteReleaseTaskById(id);
        return flag;
    }


}
